import dbus
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)

from coherence.extern.telepathy import tube, stream
from coherence.extern.telepathy import connect
import gst
import gobject
import sys

class GstStreamServer(stream.TrivialStreamServer):

    def __init__(self, publisher):
        stream.TrivialStreamServer.__init__(self)
        self.clients = {}
        self.publisher = publisher

    def handle_client(self, sock):
        print "new client", sock
        fd = sock.fileno()
        self.clients[fd] = sock
        self.publisher._fdsink.emit("add", fd)

    def remove_client(self, fd):
        del self.clients[fd]

class GstTubePublisher(tube.TubePublisher):

    def __init__(self, connection, muc_id, tubes_to_offer):
        super(GstTubePublisher, self).__init__(connection, muc_id, tubes_to_offer)
        self._fdsink = gst.element_factory_make("multifdsink", "sink")
        self._fdsink.set_property("sync", False)
        pay = gst.element_factory_make("gdppay", "mux")
        self._src = gst.element_factory_make("videotestsrc", "src")
        self._src.set_property("is-live", True)
        self.pipeline = gst.Pipeline()
        self.pipeline.add(self._src)
        self.pipeline.add(pay)
        self.pipeline.add(self._fdsink)
        self._src.link(pay)
        pay.link(self._fdsink)
        self._fdsink.connect("client-removed", self._client_removed)

    def _client_removed(self, sink, fd, client_status):
        self.server.remove_client(fd)

    def muc_joined(self):
        super(GstTubePublisher, self).muc_joined()
        self.server = GstStreamServer(self)
        self.server.run()
        socket_address = self.server.socket_address
        self.socket_address = (socket_address[0],
                               dbus.UInt16(socket_address[1]))
        service = "x-test"
        params = {}
        self.offer_stream_tube(service, params, self.socket_address)
        self.pipeline.set_state(gst.STATE_PLAYING)

class GstTubeConsumer(tube.TubeConsumer):

    def __init__(self, connection, muc_id, found_peer_callback=None,
                 disapeared_peer_callback=None):
        super(GstTubeConsumer, self).__init__(connection, muc_id,
                                              found_peer_callback=found_peer_callback,
                                              disapeared_peer_callback=disapeared_peer_callback)
        self._fdsrc = gst.element_factory_make("fdsrc")
        depay = gst.element_factory_make("gdpdepay")
        self._sink = gst.element_factory_make("xvimagesink")
        self.pipeline = gst.Pipeline()
        self.pipeline.add(self._fdsrc)
        self.pipeline.add(depay)
        self.pipeline.add(self._sink)
        self._fdsrc.link(depay)
        depay.link(self._sink)

    def plug_stream(self, address):
        super(GstTubeConsumer, self).plug_stream(address)
        self.client = stream.TrivialStreamClient(address)
        self.client.connect()
        fd = self.client._socket.fileno()
        self._fdsrc.set_property("fd", fd)
        self.pipeline.set_state(gst.STATE_PLAYING)

loop = gobject.MainLoop()
muc_id = "Test"
manager = "salut"
protocol = "local-xmpp"

if sys.argv[1] == "client":
    account = {'first-name': 'Phil',
               'last-name': '',
               'nickname':  'philn',
               'published-name': 'Phil'}
    connection = connect.tp_connect(manager, protocol, account)
    obj = GstTubeConsumer(connection, muc_id)
else:
    account = {'first-name': 'Phil22',
               'last-name': '',
               'nickname':  'philn2',
               'published-name': 'Phil2'}
    connection = connect.tp_connect(manager, protocol, account)
    obj = GstTubePublisher(connection, muc_id, {})

obj.start()
try:
    loop.run()
finally:
    obj.stop()
    loop.quit()
